home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / net3d-0.08 / file.c < prev    next >
C/C++ Source or Header  |  1995-06-22  |  25KB  |  1,094 lines

  1. /* file.c
  2.  *
  3.  * Functions for reading in a vehicle from a file
  4.  */
  5.  
  6. #include "net3d.h"
  7.  
  8. static char *ownernames[OWNERCOUNT] = {    "player",
  9.                     "game",
  10.                     "network",
  11.                     "none" };
  12.  
  13. static char *weaponnames[WEAPONCOUNT] = {"none",
  14.                      "tracer",
  15.                      "shell",
  16.                      "bullet",
  17.                      "bomb",
  18.                      "flame",
  19.                      "missile",
  20.                      "chicken",
  21.                      "plasmaballs",
  22.                      "torpedo"};
  23.  
  24. static char *typenames[TYPECOUNT] = {"tank",
  25.                      "fish",
  26.                      "bird",
  27.                      "shrapnel",
  28.                      "static",
  29.                      "bullet",
  30.                      "hover",
  31.                      "scenery",
  32.                      "fixedwing",
  33.                      "thing",
  34.                      "missile",
  35.                      "tree",
  36.                      "seedpod",
  37.                      "gunsite",
  38.                      "mine",
  39.                      "weapon",
  40.                      "munitions",};
  41.  
  42. int linenum;            /* line up to in reading a file desc. */
  43. static char *filename;        /* name of file being read */
  44. static pid_t childpid = 0;    /* current child process being used
  45.                  * for piping */
  46.  
  47. /* reads the next token from the input file, allowing for comments */
  48. void ntoken(int fp, char *s)
  49. {
  50. /* zero string, and read in a new one (hopefully) */
  51. s[0]='\0';
  52. strcpy(s,ngetw(fp));
  53.  
  54. /* printf("%s\n",s); */
  55.  
  56. /* anything inside a standard c-style comment is ignored */
  57. if (!strcmp(s,"/*")) {
  58.     while(strcmp(s,"*/"))
  59.         ntoken(fp,s);
  60.     ntoken(fp,s);
  61.     }
  62. /* a line beginning with # is from cpp, and gives the line number and
  63.  * maybe the file name.
  64.  */
  65. if (!strcmp(s,"#")) {
  66.     char *cppinfo;
  67.     char *lnum, *fname;
  68.  
  69.     cppinfo = ngets(fp);
  70.     lnum = strtok(cppinfo," \t");
  71.     linenum = atoi(lnum) - 1;
  72.     if ((fname = strtok(NULL," \t"))) {
  73.         /* A file name is provided */
  74.         filename = strdupe(fname);
  75.         }
  76.     ntoken(fp,s);
  77.     }
  78. }
  79.  
  80. /* duplicates some memory */
  81. void *dupe(void *mem, int size)
  82. {
  83. void *newm;
  84. newm=(void *)malloc(size);
  85. memcpy(newm,mem,size);
  86. return newm;
  87. }
  88.  
  89. /* duplicates a string */
  90. char *strdupe(char *s)
  91. {
  92. char *news;
  93.  
  94. if (s) {
  95.     news=(char *)malloc(strlen(s)+1);
  96.     strcpy(news,s);
  97.     return news;
  98.     }
  99. else
  100.     return NULL;
  101. }
  102.  
  103. /* prints an error encountered during parsing of 3d input file */
  104. void fileerror(char *msg, char *tok, int fp)
  105. {
  106. fprintf(stderr,"Vehicle file error at line %d in %s:\n",linenum,filename);
  107. fprintf(stderr,"%s : %s\n",msg,tok);
  108. close(fp);
  109. if (childpid) {
  110.     /* If a child process has been forked to pipe a vehicle file
  111.      * though cpp, kill it. */
  112.     kill(childpid,SIGTERM);
  113.     }
  114. exit(1);
  115. }
  116.  
  117. /* reads a file containing 3-d definitions of vehicles, each made
  118.  * up of a number of objects */
  119. void readfile(struct object **ohead, struct vehicle **vhead, int fp,
  120.  struct map *mp)
  121. {
  122. char tok[100]={0};
  123. struct vehicle *nv;
  124. struct object *no;
  125. int end=0;
  126. struct vehicle **dvhead;
  127. struct object **dohead;
  128.  
  129. linenum = 1;
  130. filename = "unknown";
  131.  
  132. dvhead = &evhead;
  133. dohead = &eohead;
  134. /* note - need code to handle errors in vehicle file */
  135. while(!end) {
  136.     ntoken(fp,tok);
  137.     if (!strcmp(tok,"vehicle")) {
  138.         /* create a new vehicle */
  139.         int endv=0;
  140.         float xoff=0,yoff=0,zoff=0;
  141.         bool def=false;
  142.  
  143. #if DEBUG
  144.             printf("Reading vehicle\n");
  145. #endif
  146.         nv=(struct vehicle *)calloc(1,sizeof(struct vehicle));
  147.         nv->partcount=0;
  148.         nv->parts=(struct object **)calloc(MAX_PARTS_PER_VEHICLE,
  149.                            sizeof(struct object *));
  150.         nv->owner          = o_game;
  151.         nv->type           = t_bird;
  152.         nv->weapon         = w_none;
  153.         nv->velocity       = 0.0;
  154.         nv->angle          = 0.0;
  155.                 nv->angle_vel      = 0.0;
  156.         nv->turret_ang     = 0.0;
  157.         nv->flying         = false;
  158.         nv->hp             = 5;
  159.         nv->alive          = true;
  160.         nv->vid            = vidcount++;
  161.         nv->target         = -1;
  162.         nv->reload         = 0;
  163.         nv->range          = 0;
  164.         nv->max.velocity   = vmax[nv->type];
  165.         nv->max.angle_vel  = MAX_ANGLE_VEL;
  166.         nv->max.altitude   = MAX_ALTITUDE;
  167.         nv->max.turret_ang = MAX_TURRET_ANG;
  168.         nv->max.treeheight = 40;
  169.         nv->lock           = -1;
  170.         nv->transfer       = -1;
  171.         nv->missile        = -1;
  172.         nv->ammo           = 20;
  173.         nv->res            = 0;
  174.         nv->vm9vid         = -1;
  175.         nv->buildervid     = -1;
  176.         nv->seed           = NULL;
  177.         nv->pnum           = -1;
  178.         nv->stcount       = 0;
  179.         nv->states       = calloc(MAX_STATES_PER_VEHICLE,
  180.                         sizeof(struct state **));
  181.         nv->currentstate   = -1;
  182.         nv->lasthit       = -1.0;
  183.         nv->lastvid       = -1;
  184.         nv->ftimer       = 0.0;
  185.         nv->bumped       = False;
  186.  
  187.         /* read vehicle name */
  188.         ntoken(fp,tok);
  189.         nv->code=(char *)malloc(strlen(tok)+1);
  190.         strcpy(nv->code,tok);
  191.  
  192.         /* check for { or def */
  193.         ntoken(fp,tok);
  194.         if (!strcmp(tok,"def")) {
  195.             /* this is a definition only */
  196.             def = true;
  197.             nv->next = (*dvhead);
  198.             (*dvhead) = nv;
  199.             ntoken(fp,tok);
  200.             }
  201.         else if (!strcmp(tok,"{")) {
  202.             nv->next=(*vhead);
  203.             (*vhead)=nv;
  204.             }
  205. #if DEBUG
  206.             printf("reading in %s\n",tok);
  207. #endif
  208.         while(!endv) {
  209.             ntoken(fp,tok);
  210.             if (!strcmp(tok,"name")) {
  211.                 /* read vehicle name */
  212.                 char name[100];
  213.                 int i=0;
  214.                 char futplex;
  215.  
  216. #if DEBUG
  217.                 printf("Reading name\n");
  218. #endif
  219.                 read(fp,&futplex,1);    /* skip " */
  220.                 do {
  221.                     read(fp,name+i,1);
  222.                     } while(name[i++] != '\"');
  223.                 name[i-1]='\0';
  224.                 nv->name=(char *)malloc(strlen(name)+1);
  225.                 strcpy(nv->name,name);
  226.                 }
  227.             else if (!strcmp(tok,"object")) {
  228.                 /* read in an object of this vehicle */
  229.                 int endo=0;
  230.                 float xo=0,yo=0,zo=0;
  231.  
  232.                 if (nv->partcount >= MAX_PARTS_PER_VEHICLE)
  233.                     fileerror("Maximum objects per "
  234.                      "vehicle limit reached","",fp);
  235. #if DEBUG
  236.                     printf("Reading object\n");
  237. #endif
  238.                 no = (struct object *)calloc(1,sizeof(
  239.                                  struct object));
  240.                 no->cent.x = no->cent.y=no->cent.z=0.0;
  241.                 no->pcount = 0;
  242.                 no->fcount = 0;
  243.                 no->parent = nv;
  244.                 no->faces = (struct polygon *)calloc(
  245.                         MAX_FACES_PER_OBJECT,
  246.                         sizeof(struct polygon));
  247.                 no->clockwise = true;
  248.                 no->angle_vel = 0.0;
  249.                 no->oscli = (struct oscillate *)calloc(
  250.                         MAX_OSCLI_PER_OBJECT,
  251.                         sizeof(struct oscillate));
  252.                 no->cvalid = false;
  253.                 no->mightsave = false;
  254.                 nv->parts[nv->partcount++]=no;
  255.                 /* If this object is part of a vehicle
  256.                  * definition, add it to the def's 
  257.                  * object list.
  258.                  */
  259.                 if (def) {
  260.                     no->next = (*dohead);
  261.                     (*dohead) = no;
  262.                     }
  263.                 else {
  264.                     no->next=(*ohead);
  265.                     (*ohead)=no;
  266.                     }
  267.                 ntoken(fp,tok);
  268.                 while(!endo) {
  269.                     ntoken(fp,tok);
  270.                     if (!strcmp(tok,"at")) {
  271. #if DEBUG
  272.                             printf("Reading at\n");
  273. #endif
  274.                         ntoken(fp,tok);
  275.                         no->pos.x=atof(tok);
  276.                         ntoken(fp,tok);
  277.                         no->pos.y=atof(tok);
  278.                         ntoken(fp,tok);
  279.                         no->pos.z=atof(tok);
  280.                         no->dist=0.0;
  281.                         }
  282.                     else if (!strcmp(tok,"centre")) {
  283. #if DEBUG
  284.                             printf("reading "
  285.                              "centre\n");
  286. #endif
  287.                         ntoken(fp,tok);
  288.                         no->cent.x=atof(tok);
  289.                         ntoken(fp,tok);
  290.                         no->cent.y=atof(tok);
  291.                         ntoken(fp,tok);
  292.                         no->cent.z=atof(tok);
  293.                         }
  294.                     else if (!strcmp(tok,"points")) {
  295.                         /* read in object points */
  296.                         ntoken(fp,tok);
  297.                         readpoints(no,fp);
  298.                         }
  299.                     else if (!strcmp(tok,"face")) {
  300.                         /* read in a face */
  301.                         readface(no,fp);
  302.                         }
  303.                     else if (!strcmp(tok,"counter")) {
  304.                         no->clockwise=false;
  305.                         }
  306.                     else if (!strcmp(tok,"angle_velocity")){
  307.                         ntoken(fp,tok);
  308.                         no->angle_vel=dtor(atof(tok));
  309.                         }
  310.                     else if (!strcmp(tok,"offset")) {
  311.                         /* add offset to an object */
  312.                         ntoken(fp,tok);
  313.                         xo=atof(tok);
  314.                         ntoken(fp,tok);
  315.                         yo=atof(tok);
  316.                         ntoken(fp,tok);
  317.                         zo=atof(tok);
  318.                         }
  319.                     else if (!strcmp(tok,"oscli") ||
  320.                          !strcmp(tok,"bounce")) {
  321.                         int o;
  322.  
  323.                         if (no->ocount >=
  324.                             MAX_OSCLI_PER_OBJECT)
  325.                             fileerror("Maximum "
  326.                              "oscli per object "
  327.                              "limit reached","",fp);
  328.                         o=no->ocount++;
  329.                         /* oscillation function */
  330.                         if (tok[0]=='o') {
  331.                             no->oscli[o].func =
  332.                              sinhalf;
  333.                             }
  334.                         else if (tok[0]=='b') {
  335.                             no->oscli[o].func =
  336.                              sinsq;
  337.                             }
  338.                         /* point to oscillate */
  339.                         ntoken(fp,tok);
  340.                         if (atoi(tok) == -1) {
  341.                             no->oscli[o].pt =
  342.                              &(no->pos);
  343.                             }
  344.                         else {
  345.                             no->oscli[o].pt = 
  346.                              &(no->points[atoi(tok)]);
  347.                             }
  348.                         no->oscli[o].pnum = atoi(tok);
  349.  
  350.                         no->oscli[o].init =
  351.                          *(no->oscli[o].pt);
  352.                         /* oscillation rate */
  353.                         ntoken(fp,tok);
  354.                         no->oscli[o].rate=atof(tok);
  355.                         /* get oscli vector
  356.                          * and axis flags
  357.                          */
  358.                         /* read { or phase */
  359.                         ntoken(fp,tok);
  360.                         if (tok[0]!='{') {
  361.                             no->oscli[o].phase
  362.                             = dtor(atof(tok));
  363.                             ntoken(fp,tok);
  364.                             }
  365.                         /* x axis */
  366.                         ntoken(fp,tok);
  367.                         if (strcmp(tok,"-")) {
  368.                             no->oscli[o].ovec.x
  369.                              = atof(tok);
  370.                             no->oscli[o].axes |=
  371.                              OSC_X_AXIS;
  372.                             }
  373.                         /* y axis */
  374.                         ntoken(fp,tok);
  375.                         if (strcmp(tok,"-")) {
  376.                             no->oscli[o].ovec.y
  377.                              = atof(tok);
  378.                             no->oscli[o].axes |=
  379.                              OSC_Y_AXIS;
  380.                             }
  381.                         /* z axis */
  382.                         ntoken(fp,tok);
  383.                         if (strcmp(tok,"-")) {
  384.                             no->oscli[o].ovec.z
  385.                              = atof(tok);
  386.                             no->oscli[o].axes |=
  387.                              OSC_Z_AXIS;
  388.                             }
  389.                         ntoken(fp,tok);    /* get } */
  390.                         }
  391.                     else if (!strcmp(tok,"turret")) {
  392.                         no->turret=true;
  393.                         }
  394.                     else if (!strcmp(tok,"rotate")) {
  395.                         readrotate(no,fp);
  396.                         }
  397.                     else if (!strcmp(tok,"scale")) {
  398.                         readscale(no,fp);
  399.                         }
  400.                     else if (!strcmp(tok,"}")) {
  401.                         /* apply offsets to object */
  402.                         int k;
  403.                         for(k=0; k<no->pcount; k++) {
  404.                             no->points[k].x += xo;
  405.                             no->points[k].y += yo;
  406.                             no->points[k].z += zo;
  407.                             }
  408.                         endo=1;
  409.                         }
  410.                     else
  411.                         fileerror("illegal token "
  412.                          "in object",tok,fp);
  413.                     }
  414.                 }
  415.             else if (!strcmp(tok,"velocity")) {
  416. #if DEBUG
  417.                     printf("Reading velocity\n");
  418. #endif
  419.                 ntoken(fp,tok);
  420.                 nv->velocity=atof(tok);
  421.                 }
  422.             else if (!strcmp(tok,"angle")) {
  423. #if DEBUG
  424.                                         printf("Reading angle\n");
  425. #endif
  426.                 ntoken(fp,tok);
  427.                 nv->angle=dtor(atof(tok));
  428.                 }
  429.             else if (!strcmp(tok,"angle_velocity")) {
  430. #if DEBUG
  431.                                         printf("Reading angle_vel\n");
  432. #endif
  433.                 ntoken(fp,tok);
  434.                 nv->angle_vel=dtor(atof(tok));
  435.                 }
  436.             else if (!strcmp(tok,"flying"))
  437.                 nv->flying=true;
  438.             else if (!strcmp(tok,"offset")) {
  439.                 /* add an offset to a whole vehicle */
  440.                 ntoken(fp,tok);
  441.                 xoff=atof(tok);
  442.                 ntoken(fp,tok);
  443.                 yoff=atof(tok);
  444.                 ntoken(fp,tok);
  445.                 zoff=atof(tok);
  446.                 }
  447.             else if (!strcmp(tok,"copy")) {
  448.                 /* copy another vehicle for this one.
  449.                  * makes copies of parts, partcount,
  450.                  * owner, flying, name, velocity,
  451.                                  * angle & angle_vel */
  452.                 struct vehicle *copy;
  453.  
  454.                 ntoken(fp,tok);
  455.                 for(copy=*vhead; copy; copy=copy->next)
  456.                     if (!strcmp(tok,copy->code))
  457.                         break;
  458.                 if (!copy)
  459.                     fileerror("attempted to copy non"
  460.                      " existant vehicle",tok,fp);
  461.                 copyvehicle(nv,copy,ohead);
  462.                 }
  463.             else if (!strcmp(tok,"instance")) {
  464.                 /* this vehicle is an instance of a
  465.                  * previous definition.
  466.                  */
  467.                 struct vehicle *copy;
  468.  
  469.                 ntoken(fp,tok);
  470.                 for(copy=*dvhead; copy; copy=copy->next)
  471.                     if (!strcmp(tok,copy->code))
  472.                         break;
  473.                 if (!copy)
  474.                     fileerror("attempted to instance"
  475.                      "a non-existant definition",tok,fp);
  476.                 copyvehicle(nv,copy,ohead);
  477.                 }
  478.             else if (!strcmp(tok,"type")) {
  479.                 int i;
  480.                 ntoken(fp,tok);
  481.                 for(i=0; i<TYPECOUNT; i++)
  482.                     if (!strcmp(tok,typenames[i]))
  483.                         nv->type = i;
  484.  
  485.                 /* If this is a tree, it's default seed
  486.                  * type is to form another tree.
  487.                  */
  488.                 if (nv->type == t_tree && !nv->seed)
  489.                     nv->seed = strdupe("tree");
  490.  
  491.                 /* assign a max velocity based on
  492.                  * this type.
  493.                  */
  494.                 nv->max.velocity = vmax[nv->type];
  495.                 }
  496.             else if (!strcmp(tok,"weapon")) {
  497.                 int i;
  498.                 ntoken(fp,tok);
  499.                 for(i=0; i<WEAPONCOUNT; i++)
  500.                     if (!strcmp(tok,weaponnames[i]))
  501.                         nv->weapon = i;
  502.                 }
  503.             else if (!strcmp(tok,"hp")) {
  504.                 ntoken(fp,tok);
  505.                 nv->hp=atoi(tok);
  506.                 }
  507.             else if (!strcmp(tok,"owner")) {
  508.                 int i;
  509.                 ntoken(fp,tok);
  510.                 for(i=0; i<OWNERCOUNT; i++)
  511.                     if (!strcmp(tok,ownernames[i]))
  512.                         nv->owner = i;
  513.                 }
  514.             else if (!strcmp(tok,"spin")) {
  515.                 readspin(nv,fp);
  516.                 }
  517.             else if (!strcmp(tok,"max")) {
  518.                 readmax(nv,fp);
  519.                 }
  520.             else if (!strcmp(tok,"seed")) {
  521.                 ntoken(fp,tok);
  522.                 nv->seed = strdupe(tok);
  523.                 }
  524.             else if (!strcmp(tok,"ammo")) {
  525.                 ntoken(fp,tok);
  526.                 nv->ammo = atoi(tok);
  527.                 }
  528.             else if (!strcmp(tok,"scale")) {
  529.                 readvehiclescale(nv,fp);
  530.                 }
  531.             else if (!strcmp(tok,"brain")) {
  532.                 ntoken(fp,tok);    /* absorb { */
  533.                 readbrain(nv,fp);
  534.                 }
  535.             else if (!strcmp(tok,"}")) {
  536.                 int ob;
  537.                 endv=1;
  538.                 /* change all points in the vehicle by 
  539.                  * the amount given by the offsets. 
  540.                  * also set object angles = vehicle
  541.                  * angle */
  542.                 for(ob=0; ob<nv->partcount; ob++) {
  543.                     nv->parts[ob]->pos.x += xoff;
  544.                     nv->parts[ob]->pos.y += yoff;
  545.                     nv->parts[ob]->pos.z += zoff;
  546.                     nv->parts[ob]->angle = nv->angle;
  547.                     }
  548.                 /* calculate initial points for all
  549.                  * oscli's in objects.
  550.                  */
  551.                 for(ob=0; ob<nv->partcount; ob++) {
  552.                     int os,oc;
  553.                     oc = nv->parts[ob]->ocount;
  554.                     for(os=0; os<oc; os++) {
  555.                         nv->parts[ob]->oscli[os].
  556.                          init =
  557.                         *(nv->parts[ob]->oscli[os].
  558.                          pt);
  559.                         }
  560.                     }
  561.                 }
  562.             else
  563.                 fileerror("illegal token in vehicle",tok,fp);
  564.             }
  565.         }
  566.     else if (!strcmp(tok,"map")) {
  567.         int i;
  568.         /* map definition */
  569.         ntoken(fp,tok);            /* read map size */
  570.         mp->map_w=atoi(tok);
  571.         ntoken(fp,tok);
  572.         mp->map_h=atoi(tok);
  573.         ntoken(fp,tok);            /* read ground size */
  574.         mp->size=atof(tok);
  575.         ntoken(fp,tok);            /* read max height */
  576.         mp->scale=atof(tok);
  577.         ntoken(fp,tok);            /* skip a { */
  578.         
  579.         /* create map array */
  580.         mp->gr=(float **)calloc(mp->map_w,sizeof(float *));
  581.         for(i=0; i<mp->map_w; i++)
  582.             mp->gr[i]=(float *)calloc(mp->map_h,sizeof(float));
  583.         /* and height array */
  584.         mp->ht=(float **)calloc(mp->map_w,sizeof(float *));
  585.         for(i=0; i<mp->map_w; i++)
  586.             mp->ht[i]=(float *)calloc(mp->map_h,sizeof(float));
  587.         /* read in map from file, a line at a time */
  588.         for(i=0; i<mp->map_h; i++) {
  589.             int j;
  590.             ntoken(fp,tok);        /* read a map line */
  591.             if (strlen(tok) != mp->map_w)
  592.                 fileerror("map line is the wrong size",tok,fp);
  593.             for(j=0; j<mp->map_w; j++)
  594.                 mp->gr[j][i]=(tok[j]-65)/57.0*mp->scale;
  595.             }
  596.         ntoken(fp,tok);            /* skip a } */
  597.         }
  598.     else if (!strcmp(tok,"lookout")) {
  599.         /* read vmode 2 watch position */
  600.         ntoken(fp,tok);
  601.         mp->lookout.x=atof(tok);
  602.         ntoken(fp,tok);
  603.         mp->lookout.y=atof(tok);
  604.         ntoken(fp,tok);
  605.         mp->lookout.z=atof(tok);
  606.         }
  607.     else if (!strcmp(tok,"fadeto")) {
  608.         /* world fades to some colour, specified as a triple
  609.          * of 16-bit values */
  610.         ntoken(fp,tok);
  611.         mp->rfade=atoi(tok);
  612.         ntoken(fp,tok);
  613.         mp->gfade=atoi(tok);
  614.         ntoken(fp,tok);
  615.         mp->bfade=atoi(tok);
  616.         }
  617.     else if (!strcmp(tok,"ground")) {
  618.         /* colours of the ground and hills.
  619.          */
  620.         ntoken(fp,tok);
  621.         if (!strcmp(tok,"none")) {
  622.             /* No ground! */
  623.             mp->ground = False;
  624.             }
  625.         else {
  626.             mp->tcol = atoi(tok);
  627.             ntoken(fp,tok);
  628.             mp->gcol = atoi(tok);
  629.             }
  630.         }
  631.     else if (!strcmp(tok,"sky")) {
  632.         /* Colour of the sky.
  633.          */
  634.         ntoken(fp,tok);
  635.         mp->skycol = atoi(tok);
  636.         }
  637.     else if (!strcmp(tok,"stars")) {
  638.         /* stars in the sky */
  639.         ntoken(fp,tok);
  640.         createstars(mp,atoi(tok));
  641.         }
  642.     else if (!strcmp(tok,"end") || !strlen(tok)) {
  643.         end=1;
  644.         childpid = 0;        /* child should have finished */
  645.         }
  646.     else
  647.         fileerror("illegal token in file",tok,fp);
  648.     }
  649. }
  650.  
  651. /* reads the points array of an obect in from a file */
  652. void readpoints(struct object *nobj, int fp)
  653. {
  654. struct point pt[MAX_POINTS_PER_OBJECT];
  655. int i=0;
  656. char buf[100];
  657.  
  658. #if DEBUG
  659.     printf("Reading points\n");
  660. #endif
  661. do {
  662.     ntoken(fp,buf);
  663.     if (strcmp(buf,"}")) {
  664.         if (i >= MAX_POINTS_PER_OBJECT)
  665.             fileerror("Maximum points per object limit reached",
  666.                   "",fp);
  667.         pt[i].x=(float)atof(buf);
  668.         ntoken(fp,buf);
  669.         pt[i].y=(float)atof(buf);
  670.         ntoken(fp,buf);
  671.         pt[i].z=(float)atof(buf);
  672.         i++;
  673.         }
  674.     } while(strcmp(buf,"}"));
  675. nobj->pcount=i;
  676. nobj->points=(struct point *)calloc(i,sizeof(struct point));
  677. memcpy(nobj->points,pt,i*sizeof(struct point));
  678.  
  679. /* allocate space for world-coord points and perspective transformed
  680.  * points. */
  681. nobj->cpoints=(struct point *)calloc(i,sizeof(struct point));
  682. nobj->ppoints=(XPoint *)calloc(i,sizeof(XPoint));
  683. }
  684.  
  685. /* reads a face of an object and it's list of points from a file */
  686. void readface(struct object *nobj, int fp)
  687. {
  688. struct polygon *npoly;
  689. int pt[MAX_POINTS_PER_FACE];
  690. int i=0;
  691. char tok[100];
  692.  
  693. if (nobj->fcount >= MAX_FACES_PER_OBJECT)
  694.     fileerror("Maximum faces per object limit reached","",fp);
  695. #if DEBUG
  696.     printf("Reading face\n");
  697. #endif
  698. npoly=(struct polygon *)malloc(sizeof(struct polygon));
  699.  
  700. /* read in colour */
  701. ntoken(fp,tok);
  702. npoly->colour=atol(tok);
  703.  
  704. /* read in and assign face style */
  705. ntoken(fp,tok);
  706. switch(tok[0]) {
  707. case 'f':
  708.     npoly->type=f_face;
  709.     break;
  710. case 'p':
  711.     npoly->type=f_plane;
  712.     break;
  713. case 'l':
  714.     npoly->type=f_line;
  715.     break;
  716. case 'w':
  717.     npoly->type=f_wireframe;
  718.     break;
  719. case 'g':
  720.     npoly->type=f_glass;
  721.     break;
  722. case 'c':
  723.     npoly->type=f_sphere;
  724.     break;
  725. case 'd':
  726.     npoly->type=f_point;
  727.     break;
  728. case 's':
  729.     npoly->type=f_shaded;
  730.     break;
  731. default:
  732.     fileerror("Unknown face type",tok,fp);
  733.     break;
  734.     }
  735.  
  736. /* read in list of points making up the face */
  737. ntoken(fp,tok);                /* get { */
  738. do {
  739.     if (i >= MAX_POINTS_PER_FACE)
  740.         fileerror("Maximum points per face limit reached","",fp);
  741.     ntoken(fp,tok);
  742.     if (strcmp(tok,"}")) {
  743.         pt[i]=atoi(tok);
  744.         if (pt[i] >= nobj->pcount)
  745.             fileerror("Attempted to use a non-existant point",
  746.                   "",fp);
  747.         i++;
  748.         }
  749.     } while(strcmp(tok,"}"));
  750.  
  751. if (i < 3 && npoly->type==f_face)
  752.     fileerror("A face must have at least 3 points","",fp);
  753. if (i != 2 && npoly->type==f_sphere)
  754.     fileerror("A sphere face must have only 2 points","",fp);
  755.  
  756. if (npoly->type == f_sphere) {
  757.     /* calculate the radius of the sphere.
  758.      */
  759.     float xd,yd,zd;
  760.  
  761.     xd = nobj->points[pt[0]].x - nobj->points[pt[1]].x;
  762.     yd = nobj->points[pt[0]].y - nobj->points[pt[1]].y;
  763.     zd = nobj->points[pt[0]].z - nobj->points[pt[1]].z;
  764.     npoly->radius = sqrt(xd*xd + yd*yd + zd*zd);
  765.     }
  766.  
  767. npoly->pcount=i;
  768. npoly->vertices=(int *)calloc(i,sizeof(int));
  769. memcpy(npoly->vertices,pt,i*sizeof(int));
  770. memcpy(nobj->faces+(nobj->fcount++),npoly,sizeof(struct polygon));
  771. #if DEBUG
  772.     printf("points - %d.   type - %d.   colour - %d\n",
  773.      npoly->pcount,npoly->type,npoly->colour);
  774. #endif
  775. }
  776.  
  777. /* copy one vehicle into another.
  778.  *
  779.  * nv        - destination of copy
  780.  * copy        - source of copy
  781.  * ohead    - head of the object list
  782.  */
  783. void copyvehicle(struct vehicle *nv, struct vehicle *copy,
  784.  struct object **ohead)
  785. {
  786. int o,s;
  787.  
  788. /* do the copying */
  789. nv->partcount    = copy->partcount;
  790. nv->type         = copy->type;
  791. nv->owner        = copy->owner;
  792. nv->weapon       = copy->weapon;
  793. nv->flying       = copy->flying;
  794. nv->name         = strdupe(copy->name);
  795. nv->velocity     = copy->velocity;
  796. nv->angle        = copy->angle;
  797. nv->angle_vel    = copy->angle_vel;
  798. nv->hp           = copy->hp;
  799. nv->max          = copy->max;
  800. nv->transfer     = copy->transfer;
  801. nv->ammo         = copy->ammo;
  802. nv->vm9vid       = copy->vm9vid;
  803. nv->buildervid   = copy->buildervid;
  804. nv->turret_ang   = copy->turret_ang;
  805. nv->seed         = strdupe(copy->seed);
  806. nv->pnum     = copy->pnum;
  807. nv->lasthit     = copy->lasthit;
  808. nv->spinrandom     = copy->spinrandom;
  809. if (nv->spinrandom) {
  810.     nv->xspin_vel = ((rand()%1000)/1000.0) * copy->xspin_vel;
  811.     nv->yspin_vel = ((rand()%1000)/1000.0) * copy->yspin_vel;
  812.     nv->zspin_vel = ((rand()%1000)/1000.0) * copy->zspin_vel;
  813.     }
  814. else {
  815.     nv->xspin_vel     = copy->xspin_vel;
  816.     nv->yspin_vel     = copy->yspin_vel;
  817.     nv->zspin_vel     = copy->zspin_vel;
  818.     }
  819.  
  820. /* copy brain */
  821. nv->currentstate    = copy->currentstate;
  822. nv->stcount        = copy->stcount;
  823. nv->states = dupe(copy->states,
  824.           MAX_STATES_PER_VEHICLE*sizeof(struct state));
  825. nv->lastvid        = copy->lastvid;
  826. nv->ftimer        = copy->ftimer;
  827. nv->bumped        = copy->bumped;
  828.  
  829. for(s=0; s<nv->stcount; s++) {
  830.     int l;
  831.  
  832.     nv->states[l].links = dupe(nv->states[l].links,
  833.                    nv->states[l].lcount*sizeof(struct link));
  834.     }
  835.     
  836.  
  837. /* copy all parts, adding the copies to the parts list */
  838. for(o=0; o<nv->partcount; o++) {
  839.     struct object *obcpy;
  840.     int p,i;
  841.  
  842.     nv->parts[o]=dupe(copy->parts[o],sizeof(struct object));
  843.     obcpy=nv->parts[o];
  844.     obcpy->next=(*ohead);
  845.     (*ohead)=obcpy;
  846.     obcpy->parent=nv;
  847.     obcpy->points=dupe(obcpy->points,
  848.                MAX_POINTS_PER_OBJECT*sizeof(struct point));
  849.     obcpy->cpoints=dupe(obcpy->cpoints,
  850.                 MAX_POINTS_PER_OBJECT*sizeof(struct point));
  851.     obcpy->ppoints=dupe(obcpy->ppoints,
  852.                 MAX_POINTS_PER_OBJECT*sizeof(XPoint));
  853.     obcpy->faces=dupe(obcpy->faces,
  854.               MAX_FACES_PER_OBJECT*sizeof(struct polygon));
  855.     obcpy->oscli=dupe(obcpy->oscli,
  856.               MAX_OSCLI_PER_OBJECT*sizeof(struct oscillate));
  857.  
  858.     /* need to change the copied oscli so that the new pointers
  859.      * in it point to the points in the copied object.
  860.      */
  861.     for(i=0; i<obcpy->ocount; i++) {
  862.         int pnum;
  863.  
  864.         pnum=obcpy->oscli[i].pnum;
  865.         if (pnum == -1) {
  866.             obcpy->oscli[i].pt = &(obcpy->pos);
  867.             }
  868.         else {
  869.             obcpy->oscli[i].pt = &(obcpy->points[pnum]);
  870.             }
  871.         }
  872.          
  873.     /* copy the vertex lists */
  874.     for(p=0; p<obcpy->fcount; p++) {
  875.         obcpy->faces[p].vertices = dupe(obcpy->faces[p].vertices,
  876.          obcpy->faces[p].pcount * sizeof(int));
  877.         }
  878.     }
  879. }
  880.  
  881. struct vehicle *findbycode(struct vehicle *vh, char *code)
  882. {
  883. for(; vh && strcmp(vh->code,code); vh=vh->next)
  884.     ;
  885. if (vh) 
  886.     return vh;
  887. else {
  888.     printf("vehicle %s not found!! this should never happen.\n",code);
  889.     exit(20);
  890.     }
  891. }
  892.  
  893. /* rotate the points of an object around the z-axis */
  894. void readrotate(struct object *ob, int fp)
  895. {
  896. char tok[100];
  897. double ang;
  898.  
  899. ntoken(fp,tok);
  900. ang=atof(tok);
  901. rotatez(ob,dtor(ang));
  902. }
  903.  
  904. /* scale the points of the object along the x,y and z axes */
  905. void readscale(struct object *ob, int fp)
  906. {
  907. char tok[100];
  908. float x,y,z;
  909. int i;
  910.  
  911. /* read scale factors */
  912. ntoken(fp,tok);
  913. x = atof(tok);
  914. ntoken(fp,tok);
  915. y = atof(tok);
  916. ntoken(fp,tok);
  917. z = atof(tok);
  918.  
  919. /* apply them */
  920. for(i=0; i<ob->pcount; i++) {
  921.     ob->points[i].x *= x;
  922.     ob->points[i].y *= y;
  923.     ob->points[i].z *= z;
  924.     }
  925. }
  926.  
  927. void readspin(struct vehicle *nv, int fp)
  928. {
  929. char tok[100];
  930.  
  931. /* read spin velocities */
  932. ntoken(fp,tok);
  933. if (!strcmp(tok,"random")) {
  934.     /* Set spinrandom, to indicate that all copies of this vehicle
  935.      * have a random spin in the range given by the spin of this
  936.      * vehicle.
  937.      */
  938.     nv->spinrandom = True;
  939.     ntoken(fp,tok);
  940.     }
  941. nv->xspin_vel = dtor(atof(tok));
  942. ntoken(fp,tok);
  943. nv->yspin_vel = dtor(atof(tok));
  944. ntoken(fp,tok);
  945. nv->zspin_vel = dtor(atof(tok));
  946. }
  947.  
  948. /* wastecpp - when a parsing error of some kind occurs, fileerror() will
  949.  * signal the child process set up to fork off cpp. wastecpp() gets called
  950.  * and kills cpp and itself.
  951.  */
  952. static void wastecpp(int sig)
  953. {
  954. kill(childpid,SIGTERM);
  955. exit(0);
  956. }
  957.  
  958. /* returns a file descriptor that recieves the output of the command
  959.  * given by com, with argument file.
  960.  */
  961. int pipethrough(char *com, char *file)
  962. {
  963. int pfds[2];
  964. char *argv[20];
  965. int i = 1;
  966.  
  967. /* break com into command and arguments for execv */
  968. argv[0] = strtok(com," \t");
  969. while((argv[i++] = strtok(NULL," \t")) != NULL)
  970.     ;
  971. argv[i-1] = file;
  972. argv[i] = NULL;
  973.  
  974. /* set up a pipe. The forked process writes to the pipe, and the
  975.  * reading end is returned to the caller.
  976.  */
  977. pipe(pfds);
  978.  
  979. if ((childpid = fork()) == 0) {
  980.     int status;
  981.  
  982.     /* set up a signal handler, so that when fileerror() signals
  983.      * this process to die, cpp can be killed too. */
  984.     signal(SIGTERM,wastecpp);
  985.  
  986.     /* We want to do our own child reaping so we can wait(). */
  987.     signal(SIGCHLD,SIG_DFL);
  988.  
  989.     /* Re-direct stdout to go through the pipe instead */
  990.     close(1);
  991.     dup(pfds[1]);
  992.     if ((childpid = fork()) == 0) {
  993.         execv(argv[0],argv);
  994.         printf("execv returned??\n");
  995.         exit(100);
  996.         }
  997.     wait(&status);
  998.     if (status) {
  999.         /* Cpp exited with an error status. */
  1000.         printf("CPP error!\n");
  1001.         exit(1);
  1002.         }
  1003.  
  1004.     /* add an 'end', to indicate to readfile() that this vehicle is done */
  1005.     nprintf(pfds[1],"end\n");
  1006.     exit(0);
  1007.     }
  1008. return pfds[0];
  1009. }
  1010.  
  1011. /* Read in one of the maximums for a vehicle.
  1012.  */
  1013. void readmax(struct vehicle *nv, int fp)
  1014. {
  1015. char tok[100];
  1016.  
  1017. ntoken(fp,tok);
  1018. if (!strcmp(tok,"velocity")) {
  1019.     ntoken(fp,tok);
  1020.     nv->max.velocity = atof(tok);
  1021.     }
  1022. else if (!strcmp(tok,"angle_vel")) {
  1023.     ntoken(fp,tok);
  1024.     nv->max.angle_vel = atof(tok);
  1025.     }
  1026. else if (!strcmp(tok,"altitude")) {
  1027.     ntoken(fp,tok);
  1028.     nv->max.altitude = atof(tok);
  1029.     }
  1030. else if (!strcmp(tok,"turret_ang")) {
  1031.     ntoken(fp,tok);
  1032.     nv->max.turret_ang = atof(tok);
  1033.     }
  1034. else if (!strcmp(tok,"treeheight")) {
  1035.     ntoken(fp,tok);
  1036.     nv->max.treeheight = atoi(tok);
  1037.     }
  1038. }
  1039.  
  1040. /* createstars - create a list of stars, and add it to the map.
  1041.  *
  1042.  * mp        - map to add the stars to
  1043.  * scount    - number of stars to create
  1044.  */
  1045. void createstars(struct map *mp, int scount)
  1046. {
  1047. int i;
  1048. int r;
  1049.  
  1050. mp->stars  = (struct star *)calloc(scount,sizeof(struct star));
  1051. mp->scount = scount;
  1052. srand(scount);
  1053. for(i=0; i<scount; i++) {
  1054.     mp->stars[i].bearing   = dtor((rand()%3600) / 10.0);
  1055.     if (mp->ground)
  1056.         mp->stars[i].elevation = dtor((rand()%900) / 10.0);
  1057.     else
  1058.         mp->stars[i].elevation = dtor((rand()%1800) / 10.0  - 90);
  1059.     mp->stars[i].intensity = (rand()%16) + 16;
  1060.     r = rand()%10;
  1061.     mp->stars[i].radius    = (r <= 6) ? (1) : (r - 6);
  1062.     }
  1063. }
  1064.  
  1065. void readvehiclescale(struct vehicle *nv, int fp)
  1066. {
  1067. float xs,ys,zs;
  1068. int i,j;
  1069. char tok[100];
  1070.  
  1071. /* read scale factors.
  1072.  */
  1073. ntoken(fp,tok);
  1074. xs = atof(tok);
  1075. ntoken(fp,tok);
  1076. ys = atof(tok);
  1077. ntoken(fp,tok);
  1078. zs = atof(tok);
  1079.  
  1080. /* scale all objects in the vehicle.
  1081.  */
  1082. for(i=0; i<nv->partcount; i++) {
  1083.     struct object *ob;
  1084.  
  1085.     ob = nv->parts[i];
  1086.     for(j=0; j<ob->pcount; j++) {
  1087.         ob->points[j].x *= xs;
  1088.         ob->points[j].y *= ys;
  1089.         ob->points[j].z *= zs;
  1090.         }
  1091.     }
  1092. }
  1093.  
  1094.